Correct out-of-bounds memory access (#311)
authorErik Schnetter <schnetter@gmail.com>
Thu, 13 Nov 2025 19:27:18 +0000 (14:27 -0500)
committerGitHub <noreply@github.com>
Thu, 13 Nov 2025 19:27:18 +0000 (14:27 -0500)
* Correct out-of-bounds memory access

* Correct syntax error

* Add test

* Update NEWS.md

Co-authored-by: Steven G. Johnson <stevenj@alum.mit.edu>
---------

Co-authored-by: Steven G. Johnson <stevenj@alum.mit.edu>
CMakeLists.txt
MANIFEST
Makefile
NEWS.md
test/fuzzer.c
utf8proc.c
utf8proc.h

index f07f90c57841912a9c3524e77b1f040e803145d4..96fc653eaa1fc4fab52cf09c7356ba2ea703a80a 100644 (file)
@@ -5,14 +5,14 @@ include (utils.cmake)
 disallow_intree_builds()
 
 # API version - be sure to update utf8proc.h and Makefile, too!
-project (utf8proc VERSION 2.11.0 LANGUAGES C)
+project (utf8proc VERSION 2.11.1 LANGUAGES C)
 
 # This is the ABI version number, which may differ from the
 # API version number (defined in utf8proc.h and above).
 # Be sure to also update these in Makefile and MANIFEST!
 set(SO_MAJOR 3)
 set(SO_MINOR 2)
-set(SO_PATCH 0)
+set(SO_PATCH 1)
 
 option(UTF8PROC_INSTALL "Enable installation of utf8proc" On)
 option(UTF8PROC_ENABLE_TESTING "Enable testing of utf8proc" Off)
index 4bda19ad692472473c72bdef0ddc771042de3fc6..d43a5fdc9c2317eb0074318c140e7408aca0900c 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -2,8 +2,8 @@ include/
 include/utf8proc.h
 lib/
 lib/libutf8proc.a
-lib/libutf8proc.so -> libutf8proc.so.3.2.0
-lib/libutf8proc.so.2 -> libutf8proc.so.3.2.0
-lib/libutf8proc.so.3.2.0
+lib/libutf8proc.so -> libutf8proc.so.3.2.1
+lib/libutf8proc.so.2 -> libutf8proc.so.3.2.1
+lib/libutf8proc.so.3.2.1
 lib/pkgconfig/
 lib/pkgconfig/libutf8proc.pc
index 74a840ee36243c338ebed5f1ef9de8f3e629b487..0f6c2a6f4a701921428e298dc87f1962acb174c0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,10 +24,10 @@ SOFLAG = -Wl,-soname
 # Be sure to also update these ABI versions in MANIFEST and CMakeLists.txt!
 MAJOR=3
 MINOR=2
-PATCH=0
+PATCH=1
 
 # api version (also in utf8proc.h and CMakeLists.txt)
-VERSION=2.11.0
+VERSION=2.11.1
 
 OS := $(shell uname)
 ifeq ($(OS),Darwin) # MacOS X
diff --git a/NEWS.md b/NEWS.md
index e52d161120d3f772c795aba91467910e90b1e5ef..d9ccda451b196fcf3bbb73789a1b2fa86fe2d7d9 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,5 +1,11 @@
 # utf8proc release history #
 
+## Version 2.11.1 ##
+
+2025-11-04
+
+ - Correct out-of-bounds memory access when calling `utf8proc_map` with both `UTF8PROC_CHARBOUND` and `UTF8PROC_DECOMPOSE` ([#311]).
+
 ## Version 2.11.0 ##
 
 2025-09-10
index 98ce4906b5243b76880a895bedb5a4d55c2f8b0a..c6f06ada252dec25999016bc1edb067d333a8c77 100644 (file)
@@ -90,5 +90,8 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
     utf8proc_map(data, len, &str, UTF8PROC_COMPOSE | UTF8PROC_STRIPMARK);
     free(str);
 
+    utf8proc_map(data, len, &str, UTF8PROC_CHARBOUND | UTF8PROC_DECOMPOSE);
+    free(str);
+
     return 0;
-}
\ No newline at end of file
+}
index 40ea295a6d11d87cd5579bea8755dd09c9f16882..c59bad20f6096586fd2260dc738408463af2ceea 100644 (file)
@@ -595,7 +595,17 @@ UTF8PROC_DLLEXPORT utf8proc_ssize_t utf8proc_decompose_custom(
       utf8proc_int32_t uc1, uc2;
       const utf8proc_property_t *property1, *property2;
       uc1 = buffer[pos];
+      if (uc1 < 0) {
+        /* skip grapheme break */
+        pos++;
+        continue;
+      }
       uc2 = buffer[pos+1];
+      if (uc2 < 0) {
+        /* cannot recombine; skip grapheme break */
+        pos+=2;
+        continue;
+      }
       property1 = unsafe_get_property(uc1);
       property2 = unsafe_get_property(uc2);
       if (property1->combining_class > property2->combining_class &&
index 59e538936fcc12e0cdef366557cb1af31edffa91..569a21dcdae76c880afacd755656c799ba4daac2 100644 (file)
@@ -73,7 +73,7 @@
 /** The MINOR version number (increased when new functionality is added in a backwards-compatible manner). */
 #define UTF8PROC_VERSION_MINOR 11
 /** The PATCH version (increased for fixes that do not change the API). */
-#define UTF8PROC_VERSION_PATCH 0
+#define UTF8PROC_VERSION_PATCH 1
 /** @} */
 
 #include <stdlib.h>